package com.wwl.cms.basic;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author wwl
 * @version 1.0
 * @date 2021/2/18 15:50
 * @description:
 */
public class JSONObject extends HashMap<String, Object> implements Serializable {
    private static final ObjectMapper OBJECT_MAPPER = JSON.createObjectMapper();

    public JSONObject() {
        super();
    }

    public JSONObject(int initialCapacity) {
        super(initialCapacity);
    }

    public JSONObject(Map<String, Object> map) {
        super(map);
    }

    public String toJSONString() {
        return JSON.toJSONString(this);
    }

    public <T> T toJavaObject(Class<T> clazz) {
        return OBJECT_MAPPER.convertValue(this, clazz);
    }

    public JSONObject fluentPut(String key, Object value) {
        put(key, value);
        return this;
    }

    public JSONObject fluentPutAll(Map<String, ? extends Object> map) {
        putAll(map);
        return this;
    }

    public JSONObject getJSONObject(String key) {
        Object value = get(key);
        if (value == null) return null;

        if (value instanceof JSONObject) {
            return (JSONObject) value;
        }

        if (value instanceof String) {
            return JSON.parseObject((String) value, JSONObject.class);
        }

        return OBJECT_MAPPER.convertValue(value,JSONObject.class);
    }

    public JSONArray getJSONArray(String key) {
        Object value = get(key);
        if (value == null) return null;

        if (value instanceof JSONArray) {
            return (JSONArray) value;
        }

        if (value instanceof String) {
            return JSON.parseObject((String) value, JSONArray.class);
        }

        return OBJECT_MAPPER.convertValue(value,JSONArray.class);
    }

    public <T> T getJavaObject(String key, Class<T> clazz) {
        Object value = get(key);
        if (value == null) return null;

        return OBJECT_MAPPER.convertValue(value, clazz);
    }

    public <T> T getJavaObject(String key, TypeReference<T> typeReference) {
        Object value = get(key);
        if (value == null) return null;

        return OBJECT_MAPPER.convertValue(value, typeReference);
    }

    public Boolean getBoolean(String key) {
        return getJavaObject(key, Boolean.class);
    }

    public Byte getByte(String key) {
        return getJavaObject(key, Byte.class);
    }

    public byte[] getBytes(String key) {
        return getJavaObject(key, byte[].class);
    }

    public Short getShort(String key) {
        return getJavaObject(key, Short.class);
    }

    public Integer getInteger(String key) {
        return getJavaObject(key, Integer.class);
    }

    public Long getLong(String key) {
        return getJavaObject(key, Long.class);
    }

    public Float getFloat(String key) {
        return getJavaObject(key, Float.class);
    }

    public Double getDouble(String key) {
        return getJavaObject(key, Double.class);
    }

    public BigDecimal getBigDecimal(String key) {
        return getJavaObject(key, BigDecimal.class);
    }

    public BigInteger getBigInteger(String key) {
        return getJavaObject(key, BigInteger.class);
    }

    public String getString(String key) {
        return getJavaObject(key, String.class);
    }

    public Date getDate(String key) {
        return getJavaObject(key, Date.class);
    }

    public LocalTime getLocalTime(String key) {
        return getJavaObject(key, LocalTime.class);
    }

    public LocalDate getLocalDate(String key) {
        return getJavaObject(key, LocalDate.class);
    }

    public LocalDateTime getLocalDateTime(String key) {
        return getJavaObject(key, LocalDateTime.class);
    }

}
